package com.example.redis.config;

import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class OpsForApi {
    @Autowired
    private RedisTemplate redisTemplate;

    public void opsForZSet() {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("zset", "v1", 1.0);
        ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("v2", 2.0);
        ZSetOperations.TypedTuple<Object> objectTypedTuple3 = new DefaultTypedTuple<>("v3", 3.0);
        Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
        tuples.add(objectTypedTuple2);
        tuples.add(objectTypedTuple3);
        zSetOperations.add("zset", tuples);
        zSetOperations.range("zset", 0, -1);
        zSetOperations.remove("zset", "v2");
        zSetOperations.incrementScore("zset", "v3", 1.0);
        // rank -- 返回有序集中指定成员的排名
        zSetOperations.rank("zset", "v2");
        Set<Object> range = zSetOperations.range("zset", 1, 2);
        Set<ZSetOperations.TypedTuple<Object>> rangeWithScores = zSetOperations.rangeWithScores("zset", 1, 2);
        Set rangeByScore = zSetOperations.rangeByScore("zset", 1.0, 2.0);
        zSetOperations.rangeByScore("zset", 1.0, 2.0, 1, 2);
        zSetOperations.rangeByScoreWithScores("zset", 1.0, 2.0);
        Set<Object> reverseRange = zSetOperations.reverseRange("zset", 0, -1);
        Set<ZSetOperations.TypedTuple<Object>> reverseRangeWithScores = zSetOperations.reverseRangeWithScores("zset", 1, 2);
        zSetOperations.reverseRangeByScore("zset", 1.0, 2.0);
        zSetOperations.reverseRangeByScoreWithScores("zset", 1.0, 2.0, 1, 10);
        Long count = zSetOperations.count("zset", 1.0, 2.0);
        Long size = zSetOperations.size("zset");
        Long card = zSetOperations.zCard("zset");
        Double score = zSetOperations.score("zset", "v2");
        // remove
        Long removeRange = zSetOperations.removeRange("zset", 1, 2);
        Long removeRangeByScore = zSetOperations.removeRangeByScore("zset", 1.0, 2.0);
        // union 并集
        zSetOperations.unionAndStore("zset", "zset1", "dest");
        zSetOperations.unionAndStore("zset", Arrays.asList("zset1,zset2".split(",")), "dest");
        // 交集
        zSetOperations.intersectAndStore("zset", "zset1", "zset2");
        zSetOperations.intersectAndStore("zset", Arrays.asList("zset1,zset2".split(",")), "dest");
        // scan
        Cursor<ZSetOperations.TypedTuple<Object>> cursor = zSetOperations.scan("zzset1", ScanOptions.NONE);
        while (cursor.hasNext()){
            ZSetOperations.TypedTuple<Object> item = cursor.next();
            System.out.println(item.getValue() + ":" + item.getScore());
        }
    }

    public void opsForSet() {
        SetOperations setOperations = redisTemplate.opsForSet();
        setOperations.add("set", "1");
        setOperations.add("set", Arrays.asList("2"));
        setOperations.add("set", Lists.emptyList());
        // remove
        setOperations.remove("set", "1");
        // move
        setOperations.move("set", "2", "set1");
        // pop
        Object pop = setOperations.pop("set");
        List pop1 = setOperations.pop("set", 1);// 移除n个
        // size
        Long size = setOperations.size("set");
        // ismember -- 判断是否存在
        Boolean key = setOperations.isMember("key", "3");
        // member -- 集合
        Set members = setOperations.members("set");
        // 两个set的交集
        Set intersect = setOperations.intersect("set1", "set2");
        // 多个集合的交集
        Set intersect2 = setOperations.intersect("set1", Arrays.asList("set2,set3".split(",")));
        // 将set1 + set2 的交集 放入到 dest,返回处理元素的个数
        Long aLong = setOperations.intersectAndStore("set1", "set2", "dest");
        Long aLong1 = setOperations.intersectAndStore("set1", Arrays.asList("set2,set3".split(",")), "dest");
        // union -- 並集 并集
        Set union = setOperations.union("set", "set1");
        Set union1 = setOperations.union("set", Arrays.asList("set1,set2".split(",")));
        Long aLong2 = setOperations.unionAndStore("set", "set1", "dest");
        setOperations.unionAndStore("set", Arrays.asList("set1,set2".split(",")), "desc");
        // 差集 difference
        Set difference = setOperations.difference("set", "set1");
        Set difference1 = setOperations.difference("set", Arrays.asList("set2,dest"));
        setOperations.differenceAndStore("set", "set1", "dest");
        setOperations.differenceAndStore("set", Arrays.asList("set1,set2".split(",")), "dest");
        // members -查询
        Set members1 = setOperations.members("set");
        Object object = setOperations.randomMember("set");
        List list = setOperations.randomMembers("set", 10);
        Set distinctRandomMembers = setOperations.distinctRandomMembers("set", 10);
        Cursor scan = setOperations.scan("set", ScanOptions.NONE);
        while (scan.hasNext()){
            Object next = scan.next();
            System.out.println(next);
        }
    }

    public void opsForHash() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        Map<String,Object> testMap = new HashMap();
        testMap.put("name","jack");
        testMap.put("age",27);
        testMap.put("class","1");
        hashOperations.putAll("hash",testMap);

        hashOperations.delete("hash", "name");
        System.out.println(hashOperations.entries("hash"));
        // hash
        System.out.println(hashOperations.hasKey("hash", "age"));
        // get
        System.out.println(hashOperations.get("hash", "age"));
        // multiGet
        List value = hashOperations.multiGet("hash", Arrays.asList("age,name".split(",")));
        System.out.println(value);
        // increment 增加
        hashOperations.increment("hash", "age", 1);
        // keys
        Set<String> keys = hashOperations.keys("hash");
        System.out.println(keys);
        // values
        List values = hashOperations.values("hash");
        System.out.println(values);
        // put
        hashOperations.put("hash", "nickname", "haha");
        hashOperations.putIfAbsent("hash", "nickname", "bbb");
        // scan遍历
        Cursor<Map.Entry<Object, Object>> scan = hashOperations.scan("hash", ScanOptions.NONE);
        while (scan.hasNext()){
            Map.Entry<Object, Object> next = scan.next();
            System.out.println(next.getKey() + "," + next.getValue());
        }
    }

    public void opsForList() {
        ListOperations listOperations = redisTemplate.opsForList();
        List<String> ids = Lists.newArrayList();
        ids.add("1");
        ids.add("2");
        ids.add("3");
        ids.add("4");
        listOperations.rightPushAll("list", ids);
        // range --范围
        System.out.println(listOperations.range("list", 0, 1));
        // trim--裁剪集合
        listOperations.trim("list", 1, -1);// 删除第一个元素
        // size
        System.out.println(listOperations.size("list"));// 不存在返回0，类型不是list抛异常
        // put
        listOperations.leftPush("list", "1");
        listOperations.leftPushAll("list", "1", "2");
        listOperations.rightPush("list", "2");
        listOperations.rightPushAll("list", "3", "4");
        // 存时才添加
        listOperations.rightPushIfPresent("list", "5");
        listOperations.leftPushIfPresent("list", "6");
        //
        listOperations.leftPush("list", "20", "02");// 存在添加，不存在不添加
        System.out.println(listOperations.range("list", 0, -1));
        // index
        listOperations.index("list", 1);// 根据下标取值
        //pop
        listOperations.leftPop("list"); // 移除并返回
        listOperations.leftPop("list", 1, TimeUnit.HOURS); // 移除并返回,没有就等待，超时或者有值进来
        listOperations.rightPop("list"); // 移除并返回
        listOperations.rightPop("list", 2, TimeUnit.HOURS);// 移除并返回,没有就等待，超时或者有值进来
        // 将list移除的数据放入到list2中
        listOperations.rightPopAndLeftPush("list", "list2");
        listOperations.rightPopAndLeftPush("list", "list2", 1, TimeUnit.HOURS);
    }

    public void opsForValue() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("kk", "vv");
        valueOperations.set("kk2", "vv2", 1, TimeUnit.HOURS);
        valueOperations.get("kk");
        valueOperations.set("kk", "new", 1);//该方法是一个修改的方法 1是偏移量，new是新值
        //
        valueOperations.setIfAbsent("kk2", "cc");// true修改成功 false修改失败，存在时不修改
        // 批量新增
        Map<String, Object> map = new HashMap<>();
        map.put("cc", "oo");
        map.put("cc1", "oo1");
        map.put("cc2", "oo2");
        valueOperations.multiSet(map);
        valueOperations.multiSetIfAbsent(map);// 不存在才添加
        valueOperations.multiGet(Arrays.asList("cc,cc1,cc2".split(",")));// 批量查询
        // set
        Object andSet = valueOperations.getAndSet("kk", "vv33");//设置新值，返回旧值
        System.out.println(andSet);
        // increment
        valueOperations.increment("ii", 10);
        valueOperations.increment("uu");
        System.out.println(valueOperations.get("uu"));// 1-2  默认增加1
        System.out.println(valueOperations.get("ii"));// 10-20
        // append
        valueOperations.append("yy", "uuu");// key存在时累加，不存在时类似set
        // get
        String vv = valueOperations.get("kk", 0, 10);
        System.out.println(valueOperations.get("kk"));// vv33 ，不存在时返回null
        System.out.println(vv); // "vv33",不存在时返回空
        System.out.println(vv.length()); // 6
        // size
        System.out.println(valueOperations.size("kk"));
    }
}

